package com.game.code;

import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.collision.shapes.ShapeType;
import org.jbox2d.common.Transform;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.Fixture;
import org.jbox2d.dynamics.World;
import com.game.interfacesForGame.ApplicationListener;
import com.game.interfacesForImplementer.Canvas;
import com.game.interfacesForImplementer.Mouse;

public class Game implements ApplicationListener{

	public static final float WORLD_PHYSICS_SIZE = 10;

	
	World world;
	Ball ball;
	Platform platform;
	Mouse mouse;
	
	public void create(Mouse mouse) {
		
		this.mouse=mouse;
		
		Vec2 gravity = new Vec2(0.0f, 0.0f);
		boolean doSleep = true;
		world = new World(gravity,doSleep);

		

		new Border(world);


		platform = new Platform(world);

		new Level(world);
		
		ball = new Ball(world);
		ball.body.applyLinearImpulse(new Vec2(-0.2f,-0.2f),new Vec2(0,0));
		
		CollisionsListener collisionListener = new CollisionsListener();
		
		world.setContactListener(collisionListener);
		
	}

	Background background;
	
	public void resize(int width, int height) {
		background = new Background(width,height);
	}


	public void render(Canvas canvas,int refreshRate) {
		world.step((float)refreshRate/1000, 10, 1000);
		
		background.onClear(canvas);
		//background.onUpdate(refreshRate);
		//background.onDraw(canvas);
		
		//ball.onDraw(canvas);
		//platform.onDraw(canvas);
		
		ball.correctCornersAndVelocity();
		
		Vec2 p=platform.body.getPosition();
		
		int size=Math.min(canvas.getWidth(), canvas.getHeight());

		Vec2 m=new Vec2((mouse.getX()-canvas.getWidth()/2) *WORLD_PHYSICS_SIZE/size,
						(mouse.getY()-canvas.getHeight()/2)*WORLD_PHYSICS_SIZE/size);
		
		Vec2 p_force=m.sub(p);
		
		
		platform.body.setLinearVelocity(new Vec2(50*p_force.x,0));
		
		//debugging :)
		renderBodies(world,canvas);
	}
	
	private final RGB SHAPE_NOT_ACTIVE = new RGB(0.1f, 0.1f, 0.1f);
	private final RGB SHAPE_STATIC     = new RGB(0.5f, 1.0f, 0.5f);
	private final RGB SHAPE_KINEMATIC  = new RGB(0.5f, 0.9f, 0.9f);
	private final RGB SHAPE_DYNAMIC    = new RGB(0.5f, 0.5f, 0.9f);
	private final RGB SHAPE_NOT_AWAKE  = new RGB(0.6f, 0.6f, 0.6f);
	private final RGB SHAPE_AWAKE      = new RGB(0.9f, 0.7f, 0.7f);
	  
	private void renderBodies (World world,Canvas canvas) {
		Body body;
		Fixture fixture;
		for (body = world.getBodyList(); body != null; body = body.getNext()) {
			Transform transform = body.getTransform();
			for (fixture = body.getFixtureList(); fixture != null; fixture = fixture.getNext()) {
				if 		(body.isActive() == false) 			       drawShape(fixture, transform, canvas, SHAPE_NOT_ACTIVE);
			    else if (body.getType() == BodyType.STATIC)        drawShape(fixture, transform, canvas, SHAPE_STATIC);
		        else if (body.getType() == BodyType.KINEMATIC)     drawShape(fixture, transform, canvas, SHAPE_KINEMATIC);
		        else if (body.getType() == BodyType.DYNAMIC)       drawShape(fixture, transform, canvas, SHAPE_DYNAMIC);
			    else if (body.isAwake() == false) 				   drawShape(fixture, transform, canvas, SHAPE_NOT_AWAKE);
			    else 											   drawShape(fixture, transform, canvas, SHAPE_AWAKE);
			}
		}
    }

	private void drawShape(Fixture fixture, Transform transform,Canvas canvas,RGB rgb) {
		int size=Math.min(canvas.getWidth(), canvas.getHeight());


		
		if (fixture.getType() == ShapeType.CIRCLE) {
			CircleShape circle = (CircleShape) fixture.getShape();
			float r=circle.m_radius;
			//float a=transform.getAngle();
			Vec2 center = new Vec2(0,0);
			Transform.mulToOut(transform, circle.m_p, center);
			
			//current circle
			canvas.circle(canvas.getWidth()/2 +(int)(center.x*size/WORLD_PHYSICS_SIZE),
						  canvas.getHeight()/2+(int)(center.y*size/WORLD_PHYSICS_SIZE),
						  					   (int)(r  *size/WORLD_PHYSICS_SIZE),
						  rgb);

			/*
			canvas.circle(canvas.getWidth()/2 +(int)((center.x*size/WORLD_PHYSICS_SIZE)+Math.sin(a)*(r  *size/WORLD_PHYSICS_SIZE/2)),
						  canvas.getHeight()/2+(int)((center.y*size/WORLD_PHYSICS_SIZE)+Math.cos(a)*(r  *size/WORLD_PHYSICS_SIZE/2)),
						                       (int)(r  *size/WORLD_PHYSICS_SIZE/3),
				  rgb);

			canvas.circle(canvas.getWidth()/2 +(int)((center.x*size/WORLD_PHYSICS_SIZE)-Math.sin(a)*(r  *size/WORLD_PHYSICS_SIZE/2)),
			 	      	  canvas.getHeight()/2+(int)((center.y*size/WORLD_PHYSICS_SIZE)-Math.cos(a)*(r  *size/WORLD_PHYSICS_SIZE/2)),
			 	      	   					   (int)(r  *size/WORLD_PHYSICS_SIZE/3),
				  rgb);
			*/
			
	    } else {
			PolygonShape polygon = (PolygonShape)fixture.getShape();
			Vec2 p1;
			Vec2 p2;
			int i=1;
			for(i=1;i<=polygon.getVertexCount();i++){
				p1=polygon.getVertex(i-1);
				if(i==polygon.getVertexCount()) {p2=polygon.getVertex(0);} else {p2=polygon.getVertex(i);}
				
				p1=Transform.mul(transform, p1);
				p2=Transform.mul(transform, p2);


				canvas.line(canvas.getWidth()/2 +(int)(p1.x*size/WORLD_PHYSICS_SIZE),
							canvas.getHeight()/2+(int)(p1.y*size/WORLD_PHYSICS_SIZE),
							canvas.getWidth()/2 +(int)(p2.x*size/WORLD_PHYSICS_SIZE),
							canvas.getHeight()/2+(int)(p2.y*size/WORLD_PHYSICS_SIZE),rgb);

				
				/*
				canvas.line(canvas.getWidth()/2 +(int)(p1.x*canvas.getWidth() /WORLD_PHYSICS_SIZE),
							canvas.getHeight()/2+(int)(p1.y*canvas.getHeight()/WORLD_PHYSICS_SIZE),
						    canvas.getWidth()/2 +(int)(p2.x*canvas.getWidth() /WORLD_PHYSICS_SIZE),
						    canvas.getHeight()/2+(int)(p2.y*canvas.getHeight()/WORLD_PHYSICS_SIZE),rgb);
				*/
			}
	    }
	}









}
